package com.bamboo.tool.template.export.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.bamboo.tool.entity.ApiClass;
import com.bamboo.tool.entity.ApiMethod;
import com.bamboo.tool.entity.JavaFieldInfo;
import com.bamboo.tool.entity.MethodOtherInfo;
import com.bamboo.tool.enums.DataType;
import com.bamboo.tool.factory.FrameworkExecute;
import com.bamboo.tool.template.export.entity.ExPortJavaFieldInfo;
import com.bamboo.tool.template.export.entity.ExportApi;
import com.bamboo.tool.template.export.entity.ExportDirectory;
import com.bamboo.tool.util.DescProcessUtil;
import com.bamboo.tool.util.JavaFieldInfoUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bamboo
 * Date 2022/10/19 11:28
 * Description
 */
public class ExportConversionUtil {

    public static Map<String, List<ExportDirectory>> toExportDirectory(Collection<ApiClass> apiClasses) {
        Map<String, List<ExportDirectory>> map = new HashMap<>();

        List<String> allDescDart = FrameworkExecute.getAllDescDort();
        if (CollUtil.isEmpty(apiClasses)) {
            return map;
        }
        for (ApiClass classz : apiClasses) {
            List<ExportDirectory> exportDirectories = map.get(classz.getProjectId());
            if (exportDirectories == null) {
                map.put(classz.getProjectId(), new ArrayList<>());
                exportDirectories = map.get(classz.getProjectId());
            }

            String classDesc = DescProcessUtil.getClassDesc(classz, allDescDart);
            ExportDirectory exportDirectory = new ExportDirectory();
            exportDirectory.setDirectoryTitle(classDesc);
            exportDirectory.setProjectName(classz.getProjectName());
            exportDirectories.add(exportDirectory);

            for (ApiMethod method : classz.getMethods()) {
                ExportApi exportApi = new ExportApi();
                MethodOtherInfo otherInfo = method.getOtherInfo();
                String author = otherInfo.getAuthor();
                exportApi.setAuthor(author);
                exportApi.setContentType(otherInfo.getContentType());
                exportApi.setRequestTypes(method.getRequestMethods());
                String methodDesc = DescProcessUtil.getMethodDesc(method, allDescDart);
                exportApi.setTitle(methodDesc);
                List<ExPortJavaFieldInfo> headParams = otherInfo.getHeadParams().stream().map(e -> toExPortJavaFieldInfo(e, allDescDart)).collect(Collectors.toList());
                List<ExPortJavaFieldInfo> queryParams = otherInfo.getQueryParams().stream().map(e -> toExPortJavaFieldInfo(e, allDescDart)).collect(Collectors.toList());
                List<ExPortJavaFieldInfo> pathParams = otherInfo.getPathParams().stream().map(e -> toExPortJavaFieldInfo(e, allDescDart)).collect(Collectors.toList());
                exportApi.setHeadParams(headParams);
                exportApi.setPathParams(pathParams);

                exportApi.setRequestPath(method.getMethodUrl());
                exportApi.setQueryParams(queryParams);
                if (!otherInfo.getResponseParam().getFieldType().equals(DataType.VOID)) {
                    exportApi.setResponseParam(toExPortJavaFieldInfo(otherInfo.getResponseParam(), allDescDart));
                }
                if (otherInfo.getBodyParams().size() > 0) {
                    JavaFieldInfo javaFieldInfo = otherInfo.getBodyParams().get(0);
                    List<JavaFieldInfo> children = javaFieldInfo.getChildren();
                    Object bodyJson = JavaFieldInfoUtil.toJson(otherInfo.getBodyParams().get(0));
                    if (bodyJson != null) {
                        exportApi.setBodyJson(JSONObject.toJSONString(bodyJson, true));
                    }
                    List<ExPortJavaFieldInfo> bodyParams = null;
                    if (CollUtil.isNotEmpty(children)) {
                        bodyParams = children.stream().map(e -> toExPortJavaFieldInfo(e, allDescDart)).collect(Collectors.toList());
                    } else {
                        ExPortJavaFieldInfo exPortJavaFieldInfo = toExPortJavaFieldInfo(javaFieldInfo, allDescDart);
                        bodyParams = Arrays.asList(exPortJavaFieldInfo);
                    }
                    exportApi.setBodyParams(bodyParams);
                }

                Object returnJson = JavaFieldInfoUtil.toJson(otherInfo.getResponseParam());
                if (returnJson != null) {
                    exportApi.setResponseJson(JSONObject.toJSONString(returnJson, true));
                }
                exportDirectory.getApis().add(exportApi);
            }

        }
        return map;
    }

    public static ExPortJavaFieldInfo toExPortJavaFieldInfo(JavaFieldInfo javaFieldInfo, List<String> allDescDart) {
        ExPortJavaFieldInfo exPortJavaFieldInfo = new ExPortJavaFieldInfo();
        exPortJavaFieldInfo.setFieldName(javaFieldInfo.getFieldName());
        if (javaFieldInfo.getArrayType() != null) {
            if (javaFieldInfo.getArrayType().equals(DataType.LIST) || javaFieldInfo.getArrayType().equals(DataType.SET)) {
                if (javaFieldInfo.getFieldType().equals(DataType.OBJECT)) {
                    exPortJavaFieldInfo.setFieldType(javaFieldInfo.getArrayType().getCode());
                } else {
                    exPortJavaFieldInfo.setFieldType(javaFieldInfo.getArrayType().getCode() + "<" + javaFieldInfo.getFieldType().getCode() + ">");
                }
            } else if (javaFieldInfo.getArrayType().equals(DataType.ARRAY)) {
                exPortJavaFieldInfo.setFieldType(javaFieldInfo.getFieldType().getCode() + "[]");
            }
        } else {
            exPortJavaFieldInfo.setFieldType(javaFieldInfo.getFieldType().getCode());
        }
        exPortJavaFieldInfo.setMaxLength(javaFieldInfo.getMaxLength());
        exPortJavaFieldInfo.setMinLength(javaFieldInfo.getMinLength());
        exPortJavaFieldInfo.setDefaultValue(javaFieldInfo.getDefaultValue());
        String desc = DescProcessUtil.getDesc(allDescDart, javaFieldInfo.getDesc());
        if (StrUtil.isNotBlank(desc) && desc.contains("\n")) {
            exPortJavaFieldInfo.setDesc(StrUtil.replace(desc, "\n", "<br/>"));
        } else {
            exPortJavaFieldInfo.setDesc(desc);
        }

        exPortJavaFieldInfo.setRequired(javaFieldInfo.isRequired());
        if (CollUtil.isNotEmpty(javaFieldInfo.getChildren())) {
            javaFieldInfo.getChildren().forEach(e -> {
                        ExPortJavaFieldInfo exPortJavaFieldInfo1 = toExPortJavaFieldInfo(e, allDescDart);
                        exPortJavaFieldInfo.getChildren().add(exPortJavaFieldInfo1);
                    }

            );

        }
        return exPortJavaFieldInfo;
    }
}
